import json
import datetime
import decimal
from sqlalchemy.ext.declarative import DeclarativeMeta


def convert_to_dict(obj):
    """把Object对象转换成Dict对象"""
    dict = {}
    dict.update(obj.__dict__)
    return dict


def convert_to_dicts(objs):
    """把对象列表转换为字典列表"""
    obj_arr = []

    for o in objs:
        # 把Object对象转换成Dict对象
        dict = {}
        dict.update(o.__dict__)
        obj_arr.append(dict)

    return obj_arr


def class_to_dict(obj):
    """把对象(支持单个对象、list、set)转换成字典"""
    is_list = obj.__class__ == [].__class__
    is_set = obj.__class__ == set().__class__

    if is_list or is_set:
        obj_arr = []
        for o in obj:
            # 把Object对象转换成Dict对象
            dict = {}
            dict.update(o.__dict__)
            obj_arr.append(dict)
        return obj_arr
    else:
        dict = {}
        dict.update(obj.__dict__)
        return dict


# sqlalchemy to json
# 只写方法，具体实现流程、数据库连接、数据库表这些内容看前面的文章
# 注：仅供参考，具体情况需具体编写

class AlchemyEncoder(json.JSONEncoder):
    """
    SqlAlchemy对象转换为json格式
    """

    def default(self, obj):
        if isinstance(obj.__class__, DeclarativeMeta):
            fields = {}
            for field in [x for x in dir(obj) if not x.startswith('_') and x != 'metadata']:
                data = obj.__getattribute__(field)
                try:
                    if type(data) is datetime.datetime:
                        data = data.strftime("%Y-%m-%d %H:%M:%S")
                    elif isinstance(data, decimal.Decimal):
                        data = float(data)
                    else:
                        json.dumps(data)
                    fields[field] = data
                except TypeError:
                    fields[field] = None
            return fields
        return json.JSONEncoder.default(self, obj)


class DecimalEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, decimal.Decimal):
            return float(o)
        super(DecimalEncoder, self).default(o)
